﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Script.Serialization;
using System.Windows.Forms;
using Fiddler;
using FiddlerExUtils.Helper;
using FiddlerExUtils.Properties;
using FiddlerExUtils.Tools;

namespace FiddlerExUtils.UserControls
{
    public partial class RichTextBoxControl : UserControl
    {
        private bool isSearchNext = true;
        private int _searchIndex = 0;//查找开始位置

        public RichTextBoxControl()
        {
            InitializeComponent();

            richTextBox1.AllowDrop = true;
            //richTextBox1.EnableAutoDragDrop = true;

        }

        private void Btn_SearchNext_Click(object sender, EventArgs e)
        {
            isSearchNext = true;
            var findWord = TB_Search.Text.Trim();
            if (string.IsNullOrEmpty(findWord) || string.IsNullOrEmpty(richTextBox1.Text.Trim()))
            {
                richTextBox1.Select(_searchIndex, 0);
                return;
            }

            var searchResult = richTextBox1.Find(findWord, _searchIndex, RichTextBoxFinds.None);
            if (searchResult == -1)
            {
                if (_searchIndex == 0)
                {
                    richTextBox1.Select(_searchIndex, 0);
                    MessageBox.Show("未找到相关内容！");
                }
                _searchIndex = 0;
            }
            else
            {
                richTextBox1.Focus();
                richTextBox1.Select(searchResult, findWord.Length);
                //richTextBox1.SelectionFont = new Font("Times New Roman", (float)12, FontStyle.Bold);
                _searchIndex = searchResult + findWord.Length;
                TB_Search.Focus();
            }
        }

        private void Btn_SearchPrevious_Click(object sender, EventArgs e)
        {
            isSearchNext = false;
            var findWord = TB_Search.Text.Trim();
            if (string.IsNullOrEmpty(findWord) || string.IsNullOrEmpty(richTextBox1.Text.Trim()))
            {
                richTextBox1.Select(_searchIndex, 0);
                return;
            }

            var searchResult = richTextBox1.Find(findWord, 0, _searchIndex, RichTextBoxFinds.Reverse);
            if (searchResult == -1)
            {
                if (_searchIndex == 0)
                {
                    richTextBox1.Select(_searchIndex, 0);
                    MessageBox.Show("未找到相关内容！");
                }
                _searchIndex = 0;
            }
            else
            {
                richTextBox1.Focus();
                richTextBox1.Select(searchResult, findWord.Length);
                //richTextBox1.SelectionFont = new Font("Times New Roman", (float)12, FontStyle.Bold);
                _searchIndex = searchResult;
                TB_Search.Focus();
            }
        }

        private void TB_Search_TextChanged(object sender, EventArgs e)
        {
            _searchIndex = 0;
            if (TB_Search.Text != "")
            {
                Btn_SearchNext.Enabled = true;
                Btn_SearchPrevious.Enabled = true;
                PB_ClearText.Visible = true;
            }
            else
            {
                Btn_SearchNext.Enabled = false;
                Btn_SearchPrevious.Enabled = false;
                PB_ClearText.Visible = false;
            }

            if (isSearchNext)
            {
                Btn_SearchNext_Click(null, null);
            }
            else
            {
                Btn_SearchPrevious_Click(null, null);
            }
        }
        /// <summary>
        /// 设置RichTextBox文本框内容
        /// </summary>
        /// <param name="text"></param>
        public void SetText(string text, bool isPretty=true)
        {;
            Clear();
            bool isjson = CommonFunction.IsJson(text);
            if (isjson && isPretty)
            {
                text = CommonFunction.ConvertJsonString(text);
                byte[] array = Encoding.UTF8.GetBytes(text);
                using (MemoryStream stream = new MemoryStream(array))
                {
                    using (var sr = new StreamReader(stream))
                    {
                        string line = sr.ReadLine();
                        while (line != null)
                        {
                            if (line.Contains(":"))
                            {
                                string[] lines = line.Split(new char[] { ':' }, 2);
                                richTextBox1.SelectionColor = Color.Brown;
                                richTextBox1.AppendText(lines[0]);
                                richTextBox1.SelectionColor = Color.Black;
                                richTextBox1.AppendText(":");

                                string value_dot = lines[1];
                                
                                string value = value_dot;
                                string dot = "";
                                if (value.Contains(","))
                                {
                                    value = value.Substring(0,value.LastIndexOf(','));
                                    dot = ",";
                                }
                                
                                if (value.Trim().ToLower() == "true")
                                {
                                    richTextBox1.SelectionColor = Color.Blue;
                                }
                                else if (value.Trim().ToLower() == "false")
                                {
                                    richTextBox1.SelectionColor = Color.Blue;
                                }
                                else if (value.Trim().ToLower() == "null" || value.Trim().ToLower() == "[]" || value.Trim().ToLower() == "[")
                                {
                                    richTextBox1.SelectionColor = Color.Blue;
                                }
                                else if (value.Trim().ToLower() == "{}" || value.Trim().ToLower() == "{")
                                {
                                    richTextBox1.SelectionColor = Color.Green;
                                }
                                else if (IsNumberic(value))
                                {
                                    richTextBox1.SelectionColor = Color.Fuchsia;
                                }
                                else
                                {
                                    richTextBox1.SelectionColor = Color.Teal;
                                }

                                richTextBox1.AppendText(value);
                                richTextBox1.SelectionColor = Color.Black;
                                richTextBox1.AppendText(dot + "\n");
                            }
                            else
                            {
                                string value = line;
                                string dot = "";
                                if (value.EndsWith(","))
                                {
                                    value = value.Substring(0, value.LastIndexOf(','));
                                    dot = ",";
                                }

                                if (value.Contains("{") || value.Contains("}"))
                                {
                                    richTextBox1.SelectionColor = Color.Green;
                                }
                                else if (value.Contains("[") || value.Contains("]"))
                                {
                                    richTextBox1.SelectionColor = Color.Blue;
                                }

                                richTextBox1.AppendText(value);
                                richTextBox1.SelectionColor = Color.Black;
                                richTextBox1.AppendText(dot + "\n");
                            }
                            
                            line = sr.ReadLine();
                        };
                    }

                }
                
            }
            else
            {
                richTextBox1.Text = text;
            }
            richTextBox1.SelectionStart = 0;
        }

        //判断是否为数字
        public static bool IsNumberic(string inString)
        {
            bool result = false;
            Regex regex = new Regex(" ^ -?\\d + $");
            result =  regex.IsMatch(inString.Trim());

            if (!result)
            {
                Regex regex1 = new Regex("^(-?\\d+)(\\.\\d+)?$");
                result = regex1.IsMatch(inString.Trim());
            }
            return result;
        }

        public void Test(Dictionary<string, object> dictionary, int start, int indent)
        {
            richTextBox1.AppendText("{");
            richTextBox1.Select(start, 1);
            richTextBox1.SelectionColor = Color.Green;
            start += 1;
            richTextBox1.AppendText("\n");

            foreach (KeyValuePair<string, object> item in dictionary)
            {
                try
                {
                    dictionary = (Dictionary<string, object>)(item.Value);
                    if (dictionary != null)
                    {
                        Test(dictionary, start, indent + 4);
                        indent -= 4;
                    }
                }
                catch (Exception e)
                {
                    if (item.Value is ArrayList)//判断子节点是否是数组
                    {
                        richTextBox1.AppendText("[");
                        richTextBox1.Select(start, 1);
                        richTextBox1.SelectionColor = Color.Blue;
                        start += 1;
                        richTextBox1.AppendText("\n");

                        foreach (object obj in (ArrayList)item.Value)
                        {
                            try
                            {
                                dictionary = (Dictionary<string, object>)(obj);
                                if (dictionary != null)
                                {
                                    Test(dictionary, start, indent + 4);
                                    indent -= 4;
                                }
                            }
                            catch (Exception ex)
                            {
                            }
                        }

                        richTextBox1.AppendText("]");
                        richTextBox1.Select(start, 1);
                        richTextBox1.SelectionColor = Color.Blue;
                        start += 1;
                        richTextBox1.AppendText("\n");
                    }
                    else
                    {
                        string key = item.Key.ToString();
                        object value = item.Value;

                        //缩进
                        for (int i = 0; i < indent; i++)
                        {
                            richTextBox1.AppendText(" ");
                        }

                        //key
                        richTextBox1.AppendText(string.Format("\"{0}\"", key));
                        richTextBox1.Select(start + indent + 1, key.Length + 2);
                        richTextBox1.SelectionColor = Color.Tomato;
                        start += key.Length + 3;

                        richTextBox1.AppendText(": ");
                        start += 1;

                        //value
                        if (value.GetType() == typeof(string))
                        {
                            richTextBox1.AppendText(string.Format("\"{0}\"", value));
                            richTextBox1.Select(start + indent + 1, value.ToString().Length + 2);
                            start += value.ToString().Length + 3;
                            richTextBox1.SelectionColor = Color.DarkTurquoise;
                        }
                        else if(value.GetType() == typeof(int))
                        {
                            richTextBox1.AppendText(string.Format("{0}", value));
                            richTextBox1.Select(start + indent + 1, value.ToString().Length);
                            start += value.ToString().Length + 1;
                            richTextBox1.SelectionColor = Color.Purple;
                        }
                        else if (value.ToString().ToLower() == "true" || value.ToString() == "false" || value.ToString() == "null")
                        {
                            richTextBox1.AppendText(string.Format("{0}", value));
                            richTextBox1.Select(start + indent + 1, value.ToString().Length);
                            start += value.ToString().Length + 1;
                            richTextBox1.SelectionColor = Color.Blue;
                        }

                        richTextBox1.AppendText("\n");
                    }
                }
            }

            richTextBox1.AppendText("}");
            richTextBox1.Select(start + indent + 1, 1);
            richTextBox1.SelectionColor = Color.Green;
            start += 1;
            richTextBox1.AppendText("\n");
        }

        /// <summary>
        /// 清空RichTextBox文本框
        /// </summary>
        public void Clear()
        {
            richTextBox1.Text = "";
        }
        /// <summary>
        /// 获取RichTextBox文本框内容
        /// </summary>
        /// <returns></returns>
        public string GetText()
        {
            return richTextBox1.Text;
        }
        /// <summary>
        /// 获取RichTextBox只读状态
        /// </summary>
        /// <returns></returns>
        public bool GetReadOnly()
        {
            return richTextBox1.ReadOnly;
        }
        /// <summary>
        /// 设置RichTextBox只读状态
        /// </summary>
        /// <param name="isReadOnly"></param>
        public void SetReadOnly(bool isReadOnly)
        {
            richTextBox1.ReadOnly = isReadOnly;
        }
        /// <summary>
        /// 设置RichTextBox背景色
        /// </summary>
        /// <param name="color"></param>
        public void SetBackColor(Color color)
        {
            richTextBox1.BackColor = color;
        }
        /// <summary>
        /// 设置RichTextBox右上角图标是否显示
        /// </summary>
        /// <param name="isVisible"></param>
        public void SetToolsVisible(bool isSave, bool isParseJson, bool isCopyBody)
        {
            PB_Save.Visible = isSave;
            PB_JSONParse.Visible = isParseJson;
            PB_CopyBody.Visible = isCopyBody;
        }

        private void PB_Search_Click(object sender, EventArgs e)
        {
            PB_Search.Visible = false;
            panel1.Visible = true;
            this.Padding = new Padding(3, 33, 3, 3);
            panel1.Location = new Point(3, 3);

            if (isSearchNext)
            {
                Btn_SearchNext_Click(null, null);
            }
            else
            {
                Btn_SearchPrevious_Click(null, null);
            }
            TB_Search.Focus();
        }

        private void PB_SearchClose_Click(object sender, EventArgs e)
        {
            panel1.Visible = false;
            this.Padding = new Padding(3, 3, 3, 3);
            panel1.Location = new Point(3, 3);
            richTextBox1.Select(_searchIndex, 0);
            _searchIndex = 0;
            richTextBox1.Focus();
        }

        private void RichTextBox1_Leave(object sender, EventArgs e)
        {
            //richTextBox1.Select(_searchIndex, 0);
            PB_Search.Visible = false;
        }

        private void PB_SearchClose_MouseEnter(object sender, EventArgs e)
        {
            PB_SearchClose.BackColor = Color.LightGray;
        }

        private void PB_SearchClose_MouseLeave(object sender, EventArgs e)
        {
            PB_SearchClose.BackColor = SystemColors.Control;
        }

        private void TB_Search_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (isSearchNext)
                {
                    Btn_SearchNext_Click(null, null);
                }
                else
                {
                    Btn_SearchPrevious_Click(null, null);
                }
            }
        }

        private void RichTextBoxControl_Load(object sender, EventArgs e)
        {
            richTextBox1.LanguageOption = RichTextBoxLanguageOptions.UIFonts;
        }

        private void PB_Save_Click(object sender, EventArgs e)
        {


        }

        private void PB_JSONParse_Click(object sender, EventArgs e)
        {
            string text = richTextBox1.Text.Replace("\r", "").Replace("\n", "").Replace("\t", "").Trim();
            SetText(CommonFunction.ConvertJsonString(text, true));
        }

        private void PB_CopyBody_Click(object sender, EventArgs e)
        {
            Utilities.CopyToClipboard(richTextBox1.Text);
        }

        private void PB_JSONParse_MouseEnter(object sender, EventArgs e)
        {
            PB_JSONParse.BackColor = Color.LightGray;
        }

        private void PB_JSONParse_MouseLeave(object sender, EventArgs e)
        {
            PB_JSONParse.BackColor = Color.Transparent;
        }

        private void PB_CopyBody_MouseEnter(object sender, EventArgs e)
        {
            PB_CopyBody.BackColor = Color.LightGray;
        }

        private void PB_CopyBody_MouseLeave(object sender, EventArgs e)
        {
            PB_CopyBody.BackColor = Color.Transparent;
        }

        private void PB_Save_MouseEnter(object sender, EventArgs e)
        {
            PB_Save.BackColor = Color.LightGray;
        }

        private void PB_Save_MouseLeave(object sender, EventArgs e)
        {
            PB_Save.BackColor = Color.Transparent;
        }

        private void RichTextBox1_ReadOnlyChanged(object sender, EventArgs e)
        {
            PB_Save.Visible = !richTextBox1.ReadOnly;
            richTextBox1.BackColor = richTextBox1.ReadOnly ? SystemColors.Control : SystemColors.Window;
        }

        private void RichTextBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            if (e.KeyData == (Keys.Control | Keys.F))
            {
                PB_Search_Click(null, null);
                e.IsInputKey = true;
            }
            else if (e.KeyData == (Keys.Control | Keys.C))
            {
                if (richTextBox1.SelectedText != "")
                {
                    //Utilities.CopyToClipboard(richTextBox1.SelectedText);
                    //var content = (string)Clipboard.GetData(DataFormats.StringFormat);
                    Clipboard.Clear();
                    Clipboard.SetData(DataFormats.StringFormat, richTextBox1.SelectedText);
                }
                e.IsInputKey = true;
            }
        }

        private void PB_ClearText_Click(object sender, EventArgs e)
        {
            TB_Search.Clear();
        }

        private void PB_ClearText_MouseEnter(object sender, EventArgs e)
        {
            PB_ClearText.BackColor = Color.LightGray;
        }

        private void PB_ClearText_MouseLeave(object sender, EventArgs e)
        {
            PB_ClearText.BackColor = SystemColors.Window;
        }

        private void ContextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem == TSMI_CopyText)
            {
                if (richTextBox1.SelectedText != "")
                {
                    Utilities.CopyToClipboard(richTextBox1.SelectedText); 
                }
            }
            else if (e.ClickedItem == TSMI_PasteText)
            {
                IDataObject iData = Clipboard.GetDataObject();
                if (iData.GetDataPresent(DataFormats.Text))
                {
                    richTextBox1.SelectedText = (string)iData.GetData(DataFormats.Text);
                }
            }
            else if (e.ClickedItem == TSMI_SearchText)
            {
                PB_Search_Click(null, null);
            }
            else if (e.ClickedItem == TSMI_SelectAll)
            {
                richTextBox1.SelectAll();
            }
        }

        private void ContextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            richTextBox1.Focus();
            if (richTextBox1.Text == "")
            {
                TSMI_SelectAll.Enabled = false;
            }
            else
            {
                TSMI_SelectAll.Enabled = true;
            }
            if (richTextBox1.SelectedText == "")
            {
                TSMI_CopyText.Enabled = false;
            }
            else
            {
                TSMI_CopyText.Enabled = true;
            }
            IDataObject iData = Clipboard.GetDataObject();
            if (richTextBox1.ReadOnly || !iData.GetDataPresent(DataFormats.Text))
            {
                TSMI_PasteText.Enabled = false;
            }
            else
            {
                TSMI_PasteText.Enabled = true;
            }
        }

        private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
        {
            // 粘贴去除格式
            if (e.Control && e.KeyCode == Keys.V)
            {
                IDataObject dataObject = Clipboard.GetDataObject();
                if (dataObject.GetDataPresent(DataFormats.StringFormat))
                {
                    e.Handled = true;
                    string content = (string)Clipboard.GetData(DataFormats.StringFormat);
                    Clipboard.SetData(DataFormats.StringFormat, content);
                    richTextBox1.Paste();
                }
            }
        }
    }
}
